package com.wiz.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import javax.annotation.Resource;

import com.wiz.log.NettyInfoRecord;
import com.wiz.netty.handler.MainHandler;
import com.wiz.web.manager.ServiceManager;

public class NettyServerCenter {
	
	@Resource
	private ServiceManager serviceManager;
	@Resource
	private NettyXmlParseFactory wizXmlFactory;

	private String ip;
	private int port;
	private boolean isStart = false;

	/**
	 * 初始化方法
	 * @throws Exception
	 */
	public void init() throws Exception {
		NettyInfoRecord.infoRecord("--------start init netty-------------");
		EventLoopGroup bossGroup = new NioEventLoopGroup(2);// IO连接线程
		EventLoopGroup workerGroup = new NioEventLoopGroup();// 事件工作线程
		ServerBootstrap strap = new ServerBootstrap();
		strap.group(bossGroup, workerGroup)
				.channel(NioServerSocketChannel.class)
				//option() 方法用于设置监听套接字。childOption()则用于设置连接到服务器的客户端套接字。
				.option(ChannelOption.SO_BACKLOG, 1024)
				// 大包发送
				.option(ChannelOption.TCP_NODELAY, true)
				// ByteBuf容量动态调整的接收缓冲区分配器
				.option(ChannelOption.RCVBUF_ALLOCATOR,AdaptiveRecvByteBufAllocator.DEFAULT)
				// 内存池使用
				.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
				// 接收字节参数
				.option(ChannelOption.SO_RCVBUF, 128 * 1024)
				// 发送字节参数
				.option(ChannelOption.SO_SNDBUF, 256 * 1024)
				// .option(ChannelOption.SO_REUSEADDR, false)
				//池化分配ByteBuf
				.childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT)
//				.childOption(ChannelOption.SO_TIMEOUT,24000)
				.childOption(ChannelOption.SO_KEEPALIVE, true)
				//添加handler
				.childHandler(new MainHandler(serviceManager,wizXmlFactory));
		ChannelFuture f = strap.bind(port);
		NettyInfoRecord.infoRecord("---------netty init success------------");
		 f.awaitUninterruptibly();//等待连接完成
//		f.channel().closeFuture().sync();
		if (f.isSuccess()) {
			isStart = true;
			NettyInfoRecord.infoRecord("............wait client..............");
		} else {
			// 优雅退出，释放资源
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
			isStart = false;
			NettyInfoRecord.errorRecord("init error");
		}
	}
	
	/**
	 * 重启方法
	 * @throws Exception
	 */
	public String restart() throws Exception {
		if(!isStart){
			NettyInfoRecord.infoRecord("--------Restart init netty-------------");
			EventLoopGroup bossGroup = new NioEventLoopGroup();// IO连接线程
			EventLoopGroup workerGroup = new NioEventLoopGroup();// 事件工作线程
			ServerBootstrap strap = new ServerBootstrap();
			strap.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 1024)
					// 大包发送
					.option(ChannelOption.TCP_NODELAY, true)
					// ByteBuf容量动态调整的接收缓冲区分配器
					.option(ChannelOption.RCVBUF_ALLOCATOR,
							AdaptiveRecvByteBufAllocator.DEFAULT)
					// 内存池使用
					.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
					// 接收字节参数
					.option(ChannelOption.SO_RCVBUF, 128 * 1024)
					// 发送字节参数
					.option(ChannelOption.SO_SNDBUF, 256 * 1024)
					// .option(ChannelOption.SO_REUSEADDR, false)
					.childOption(ChannelOption.ALLOCATOR,
							PooledByteBufAllocator.DEFAULT)
					.childOption(ChannelOption.SO_KEEPALIVE, true)
					.childHandler(new MainHandler(serviceManager,wizXmlFactory));
			ChannelFuture f = strap.bind(port).sync();
			NettyInfoRecord.infoRecord("---------netty init success------------");
			// f.awaitUninterruptibly();
			f.channel().closeFuture().sync();
			if (f.isSuccess()) {
				isStart = true;
				NettyInfoRecord.infoRecord("............wait client..............");
				return "Restart success";
			} else {
				// 优雅退出，释放资源
				bossGroup.shutdownGracefully();
				workerGroup.shutdownGracefully();
				isStart = false;
				NettyInfoRecord.errorRecord("Restart error");
				return "Restart error";
			}
		}
		return "netty server is progessing";
	}
	
	/**
	 * 销毁方法
	 */
	public void destroy(){
	}

	public boolean isStart() {
		return isStart;
	}

	public void setStart(boolean isStart) {
		this.isStart = isStart;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

}
